package cn.jacksigxu.min3halla.block;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;

import javax.annotation.Nullable;

@SuppressWarnings("deprecation")
public class IngredientCanBlock extends Block {

    public static final IntegerProperty COUNT = IntegerProperty.create("count", 1, 4);
    public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;

    protected static final VoxelShape ONE_AABB = Block.box(5.0D, 0.0D, 5.0D, 11.0D, 14.0D, 11.0D);
    protected static final VoxelShape TWO_AABB_WE = Block.box(1.0D, 0.0D, 5.0D, 15.0D, 14.0D, 11.0D);
    protected static final VoxelShape TWO_AABB_NS = Block.box(5.0D, 0.0D, 1.0D, 11.0D, 14.0D, 15.0D);
    protected static final VoxelShape THREE_FOUR_AABB = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D);

    public IngredientCanBlock() {
        super(Properties.of().strength(0.25f));
        this.registerDefaultState(this.stateDefinition.any().setValue(COUNT, 1).setValue(FACING, Direction.NORTH));
    }

    @Override
    public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
        if (pPlayer.isShiftKeyDown() && pPlayer.getItemInHand(pHand).isEmpty()) {
            int count = pState.getValue(COUNT);

            if (count <= 1) {
                pLevel.removeBlock(pPos, false);
                pLevel.gameEvent(GameEvent.BLOCK_DESTROY, pPos, GameEvent.Context.of(pPlayer, pState));
            } else {
                BlockState blockstate = pState.setValue(COUNT, count - 1);
                pLevel.setBlock(pPos, blockstate, 2);
                pLevel.gameEvent(GameEvent.BLOCK_CHANGE, pPos, GameEvent.Context.of(pPlayer, blockstate));
            }
            pLevel.playSound(null, pPos, SoundEvents.ITEM_PICKUP, SoundSource.BLOCKS, 1.0F, 0.8F + pLevel.random.nextFloat() * 0.4F);

            var stack = this.getCloneItemStack(pState, pHit, pLevel, pPos, pPlayer);
            if (pPlayer.isCreative() && pPlayer.getInventory().contains(stack)) {
                return InteractionResult.sidedSuccess(pLevel.isClientSide);
            }
            if (!pPlayer.addItem(stack)) {
                ItemEntity itementity = new ItemEntity(pLevel, pPos.getX() + 0.5D, pPos.getY() + 0.5D, pPos.getZ() + 0.5D, stack);
                itementity.setPickUpDelay(40);
                pLevel.addFreshEntity(itementity);
            }
            return InteractionResult.sidedSuccess(pLevel.isClientSide);
        }
        return super.use(pState, pLevel, pPos, pPlayer, pHand, pHit);
    }

    @Override
    protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
        pBuilder.add(FACING).add(COUNT);
    }

    @Nullable
    @Override
    public BlockState getStateForPlacement(BlockPlaceContext pContext) {
        BlockState blockstate = pContext.getLevel().getBlockState(pContext.getClickedPos());
        if (blockstate.is(this)) {
            return blockstate.setValue(COUNT, Math.min(4, blockstate.getValue(COUNT) + 1));
        }
        return this.defaultBlockState().setValue(FACING, pContext.getHorizontalDirection().getOpposite());
    }

    @Override
    public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
        return switch (pState.getValue(COUNT)) {
            case 1 -> ONE_AABB;
            case 2 -> {
                Direction direction = pState.getValue(FACING);
                if (direction.getAxis() == Direction.Axis.X) {
                    yield TWO_AABB_NS;
                } else {
                    yield TWO_AABB_WE;
                }
            }
            default -> THREE_FOUR_AABB;
        };
    }

    @Override
    public boolean canBeReplaced(BlockState pState, BlockPlaceContext pUseContext) {
        return pUseContext.getItemInHand().is(this.asItem()) && pState.getValue(COUNT) < 4;
    }
}
